

#include "public.h"

/* Private typedef -----------------------------------------------------------*/
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
 
////==============F4 16K==============================================
// #define FLASH_PAGE_SIZE         ((uint32_t)0x00000400)   // FLASH Page Size 
// #define FLASH_USER_START_ADDR   ((uint32_t)0x08003C00)   // End @ of user Flash area 起始地址等于结束地址-大小+1
// #define FLASH_USER_END_ADDR     ((uint32_t)0x08003fff)   // End @ of user Flash area 64K 0X0800FFFF
//
////==============C6  32K ============================================
// #define FLASH_PAGE_SIZE         ((uint32_t)0x00000400)   // FLASH Page Size 
// #define FLASH_USER_START_ADDR   ((uint32_t)0x08007C00)   // End @ of user Flash area 起始地址等于结束地址-大小+1
// #define FLASH_USER_END_ADDR     ((uint32_t)0x08007fff)   // End @ of user Flash area 64K 0X0800FFFF

//===============C8  64k=============================================
 #define FLASH_PAGE_SIZE         1024   // FLASH Page Size 1024byte
 #define FLASH_USER_START_ADDR   ((uint32_t)0x0800fC00)   // End @ of user Flash area 起始地址等于结束地址-大小+1
 #define FLASH_USER_END_ADDR     ((uint32_t)0x0800ffff)   // End @ of user Flash area 64K 0X0800FFFF



 
uint32_t EraseCounter = 0x00;
uint32_t Address = 0x00;
uint32_t NbrOfPage = 0x00;

__IO FLASH_Status FLASHStatus = FLASH_COMPLETE;
__IO TestStatus MemoryProgramStatus = PASSED;


//uint32_t  u32WriteDataBuf[10];
//uint32_t  u32ReadData[10];
/*
 函数功能： 写FLASH 数据，
 返回值：   返回0 写数据正确， 返回值不为0 则写数据错误
*/
uint8_t WriteFlashData( uint32_t u32WriteData[ FLASH_DATA_LENGHT ] )
{  

//uint32_t  u32ReadDataBuf; // 定义一个32位无符号整数变量 u32ReadDataBuf 用于存放读取的数据缓冲区   
uint32_t  u32SumCheck=0;  // 定义一个32位无符号整数变量 u32SumCheck 用于存放数据校验和，初始化为0  
uint8_t   u8WriteFlushErr=0; // 定义一个8位无符号整数变量 u8WriteFlushErr 用于记录写入或刷新过程中的错误，初始化为0   
uint8_t   i=0; // 定义一个8位无符号整数变量 i 用于循环计数，初始化为0   

  u32SumCheck=0; // 重置校验和为0  
  u8WriteFlushErr=0; // 重置错误标志为0  
  i=0; // 重置计数器为0  

  
  FLASH_Unlock();  // 解锁FLASH存储器，使其可以进行写入和擦除操作  

  
  
  
//=============================//在写数据前必须先擦除==========================   
  
  
  
  
  FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);  // 清除FLASH的状态标志，包括结束标志（EOP）、编程错误标志（PGERR）和写保护错误标志（WRPERR）  

  // 计算要擦除的页数  
  // NbrOfPage = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;  
  // FLASH_USER_END_ADDR 和 FLASH_USER_START_ADDR 是用于定义用户FLASH存储区域的地址常量  
//  NbrOfPage = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;  
  NbrOfPage = 1;  
  // 开始擦除每一页，最多擦除 NbrOfPage 页  
  for (EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)  
  {  
      // 如果擦除当前页失败，则进行错误处理  
      if (FLASH_ErasePage(FLASH_USER_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter)) != FLASH_COMPLETE)  
      {      
          u8WriteFlushErr |= 1; // 发生了擦除错误，将错误标志的最低位设置为1  
          break; // 退出for循环  
      }  
  }  

  // 开始计算数据的校验和  
  // 循环遍历 u32WriteData 除最后一个元素外的所有数据  
  for(i = 0; i < (FLASH_DATA_LENGHT - 1); i++)  
  {  
      u32SumCheck += u32WriteData[i]; // 将数据累加到 u32SumCheck 中  
      // u32WriteDataBuf[i] = u32WriteData[i]; // 这行代码被注释掉了，表明原始数据可以写入缓冲区  
  }  

  // 将计算出的校验和保存到 u32WriteData 的最后一个位置  
  u32WriteData[i] = u32SumCheck; // 最后一个数保存为 SumCheck  
  // u32WriteDataBuf[i] = u32SumCheck; // 这行代码被注释掉了，表明校验和可以写入缓冲区  

  i = 0; // 重置计数器为0  
  Address = FLASH_USER_START_ADDR; // 设置当前写入地址为用户Flash的起始地址  

  // 写入数据到FLASH  
  while (Address < (FLASH_USER_START_ADDR + 4 * FLASH_DATA_LENGHT)) // 继续写入直到数据长度的4倍  
  {  
      // 使用 FLASH_ProgramWord 函数写入一个字到指定地址  
      if (FLASH_ProgramWord(Address, u32WriteData[i]) == FLASH_COMPLETE) // 如果写入成功  
      {  
          Address = Address + 4; // 移动到下一个地址（4字节对齐）  
          i++; // 增加计数器，准备写入下一个数据  
      }  
      else  
      {   
          u8WriteFlushErr |= 2; // 设置错误标志的第二位，标记写入错误  
          break; // 退出写操作  
      }  
  }  

  // 写入完成，锁定FLASH，防止误操作  
  FLASH_Lock();
    
  //----------------------
//  i=0;
//  Address = FLASH_USER_START_ADDR;
//  while ( Address < ( FLASH_USER_START_ADDR + 4*FLASH_DATA_LENGHT ) )
//  {
//   //  u32ReadData[i++] = *(__IO uint32_t *)Address;   //u32ReadDataBuf
//   //  if ( u32ReadData[i] != u32WriteData[i]  )
//     u32ReadDataBuf = *(__IO uint32_t *)Address;   //u32ReadDataBuf
//     if ( u32ReadDataBuf != u32WriteData[i]  )   
//     {
//         u8WriteFlushErr |= 4;;  //读错误
//     }    
//     Address = Address + 4;
//     i++;
//
//  }
//  
  return  u8WriteFlushErr;
}

/*
 函数功能： 读FLASH 数据，
 返回值：   返回1 读数据正确， 返回值为0 则读数据错误
*/

void ReadFlashData( void )
{
uint8_t i=0;  
//uint32_t  u32SumCheck=0;

    i=0;
   Address = FLASH_USER_START_ADDR;
   while ( Address < ( FLASH_USER_START_ADDR + 4*FLASH_DATA_LENGHT ))
   {
       gc.u32ReadData[i++]= *(__IO uint32_t *)Address;
       Address=Address+4;         
       if( i< (FLASH_DATA_LENGHT) )
       {
         ;         
       }
       else
       {
            return;
       }
   } 

}


/*
读取指定地址的半字(16位数据)//读ID用
也是按照半字读出，即每次读2个字节数据返回
*/

uint16_t stm32_FLASH_ReadByte( uint32_t Address ) 
{
   return *( u16*)Address;    
}





//==========================================================


void FLASH_handle ( void)  
{
//-------------------------- 延迟写数据到芯片   暂定10秒 -----------------
  

  if ( gc.WriteData_delay_cnt > gc.WriteData_delay_time)
  {
    gc.WriteData_delay_cnt = gc.WriteData_delay_time+1;//只触发一次
    
    if ( gc.WriteData_filish == 0 )
    {
      
      gc.WriteData_cmd =1;        //写数据
      gc.ReadData_cmd  =0;        //读数据
      gc.WriteData_filish =1;
    }     
  }


}












//================  flash读取存储 操作======================
void  flash_data(void)          
{
  u8 i;
//uint8_t Write_ok;
   
//   Write_ok=0;
   FLASH_handle();  //定时存储
  
   if( gc.WriteData_cmd !=0 )
   {
      gc.WriteData_cmd =0;
      
//-----写数据 到 FLASH -----
      for(i=0;i<FLASH_DATA_LENGHT;i++)
      {
        gc.u32WriteData[i] =u32RTU_C_REG[i];
      }
      
      WriteFlashData( gc.u32WriteData); 
     

//-----读数据------------
   }
   if ( gc.ReadData_cmd !=0   )
   {
      gc.ReadData_cmd = 0; 

      ReadFlashData();
      
      for(i=0;i<FLASH_DATA_LENGHT;i++)
      {
        u32RTU_C_REG[i]=gc.u32ReadData[i];        
      }      
   }
}

